function createHashHistory() {

  const historyStack = []; // hash的类似 history 的历史栈
  let current = -1; // 当前栈顶指针
  let action = "POP"; // 当前动作
  let state; // 当前状态
  let listeners = []; // 监听函数组成的数组

  const push = (pathname, nextState) => {
    action = 'PUSH'; // push->PUSH, pop->POP, replace->REPLACE
    if (typeof pathname === 'object') {
      state = pathname.state;
      pathname = pathname.pathname;
    } else {
      state = nextState;
    }

    window.location.hash = pathname; // 设置浏览器 url 的 hash 值
  }
  const listen = (listener) => {
    listeners.push(listener);

    // 返回取消监听函数
    return () => listeners = listeners.filter(_listener => _listener !== listener);
  }
  const go = (n) => {
    action = 'POP';
    const nextLocation = historyStack[current];
    current += n;

    state = nextLocation.state;
    window.location.hash = nextLocation.pathname;
  }
  const goBack = () => {
    go(-1);
  }
  const goForward = () => {
    go(1);
  }
  const history = {
    action: 'POP',
    push,
    listen,
    go,
    goBack,
    goForward,
    location: {
      pathname: '/',
      state: undefined
    }
  };

  // 类似 createBrowserHistory.js 中的 notify 函数
  const hashChangeHandler = (event) => {
    const pathname = window.location.hash.slice(1);
    const location = { pathname, state };
    Object.assign(history, { action, location});

    if (action === 'PUSH') {
      historyStack[++current] = history.location;
    }

    listeners.forEach(listener => listener(history.location));
  }

  window.addEventListener('hashchange', hashChangeHandler);
  
  if (window.location.hash) {
    action = 'PUSH';
    hashChangeHandler();
  } else {
    window.location.hash = '/';
  }

  return history;
}


export default createHashHistory;